#ifndef __USER_UDS_H__
#define __USER_UDS_H__

#include "debug.h"

#include <stdint.h>

// UDS debug
#define USER_DEBUG_EN 1

#ifdef DEBUG
#if (USER_DEBUG_EN == 1)
#define USER_UDS_LOG(sFormat, ...) SEGGER_RTT_TerminalPrintf(0, sFormat, ##__VA_ARGS__);
#else
#define USER_UDS_LOG(...)
#endif
#endif

#define UDS_APP_UPDATA_START_ADDR 0x4000      // APP运行起始地址
#define FLASH_ADDR_APP_CODE       0x10000     // APP待更新程序起始地址(备份区)
#define FLASH_ADDR_APP_CODE_MAX   0x1C000     // APP最大地址

#define APP_UPDATA_NEED_FLAG_ADDR  0x00003800 // 512B
#define APP_UPDATA_CFG_WORD        0x55AA55AA
#define APP_UPDATA_CHECK_DATA_ADDR 0x00003A00 // 512B

#define FLASH_SECTOR_SIZE 0x800               // flash扇区大小(2KByte)

#define FLASH_PAGE_SIZE (0x200)               // flash页擦除单位

#define FLASH_PROGRAM_SIZE (4)                // Flash写单位:4Byte

/*flash*/
#define FLASH_ERASE_UNIT_BYTE 2048 /*flash erase uint*/

/*flash erase*/
#define MAST_WAIT_ERASE_TIME 100         // 擦除等待时间(ms)

#define TRANSFER_DATA_BLOCK_LEN (64 + 2) // 传输数据包大小

#define CF_FRAMES_LEN 100                /*maximum length of consecutive frames*/

/*crc32*/
#define CRC32_INIT_VALUE 0xFFFFFFFF // crc init

#define FUNC_DELAY_TIME 5           // 5*10ms

typedef struct
{
    uint8_t  check_mem_routine_start_flag; // 检查内存开始标志
    uint8_t  erase_mem_routine_start_flag; // 擦除服务开始标志
    uint16_t check_mem_start_timeout;      // 检查内存开始时间
    uint16_t check_mem_finish_flag;        // 检查内存完成标志
    uint16_t erase_start_timeout;          // 擦除开始时间
    uint16_t erase_finish_flag;            // 擦除完成标志
    uint32_t flash_erase_addr;             // 擦除起始地址
    uint32_t flash_erase_size;             // 擦除内存大小
    uint32_t receive_crc32;                // 接收到的CRC
} uds_sid31_str;

typedef struct
{
    uint8_t  request_download_service_finish_flag; // 文件请求下载服务完成标志
    uint8_t  block_cnt_start_flag;                 // 数据块计数开始标志
    uint32_t flash_program_addr;                   // flash编程起始地址
    uint32_t flash_program_size;                   // flash文件大小
    uint32_t flash_program_crc;                    // flash文件CRC
} uds_sid34_str;

typedef struct
{
    uint8_t  block_cnt;      // 块序列计数
    uint16_t pack_cnt;       // 包计数
    uint16_t pack_number;    // 包总数
    uint32_t block_crc;      // 块CRC
    uint32_t total_crc;      // 总CRC
    uint32_t need_write_add; // 需要写入flash的起始地址
} uds_sid36_str;

typedef struct
{
    uint16_t soft_reset_timeout; // 软件复位超时
    uint32_t app_updata_flag;    // app更新标志
} uds_sid11_str;

typedef struct
{
    uds_sid31_str uds_sid31_service; // 31服务参数状态
    uds_sid11_str uds_sid11_service; // 11服务参数状态
    uds_sid34_str uds_sid34_service; // 34服务参数状态
    uds_sid36_str uds_sid36_service; // 36服务参数状态
} UDS_SERVICE;

extern UDS_SERVICE uds_status;

void     endian_shift(uint8_t *source, uint32_t byte_num);
uint32_t crc32_check(uint8_t *buf, uint32_t size, uint32_t crc);
uint8_t  user_flash_n_sectors_Erase(uint32_t start_addr, uint16_t n_sectors);
uint8_t  user_flash_n_page_erase(uint32_t addr, uint16_t n_page);
uint8_t  user_flash_n_word_write(uint32_t addr, uint32_t *dat, uint16_t len);
void     uds_func_poll_task(void);

#endif
